package com.wzw.shoppingcart.service;

import com.wzw.shoppingcart.entity.CartLine;
import com.wzw.shoppingcart.entity.Discount;
import com.wzw.shoppingcart.entity.Product;
import com.wzw.shoppingcart.context.PromotionContext;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;


/**
 *@author wzw
 * 2023/4/7
 */
@Service
@Slf4j
@Setter(onMethod_ = {@Autowired})
public class CartService {
    private CartLineService cartLineService;
    private ProductService productService;
    private DiscountService discountService;
    private PromotionContext promotionContext;


    public boolean addProduct(Product product, Integer amount, Integer userId) {
        Integer productId = product.getProductId();
        if (Boolean.TRUE.equals(cartLineService.exist(productId, userId))) {
            return cartLineService.addCount(amount, productId, userId);
        }

        CartLine newCartLine = new CartLine();
        newCartLine.setProductId(productId);
        newCartLine.setProductCount(amount);
        newCartLine.setUserId(userId);
        return cartLineService.save(newCartLine);
    }

    public BigDecimal calculateTotalPrice(List<CartLine> cartLines) {
        return cartLines.stream().map(c -> productService.getProductById(c.getProductId()).getPrice()
                        .multiply(BigDecimal.valueOf(c.getProductCount())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    public BigDecimal calculateDiscount(List<CartLine> cartLines, BigDecimal totalOriginPrice) {

        List<Discount> discountList = discountService.list();
        BigDecimal totalDiscountPrice = discountList.stream()
                .map(d -> promotionContext.getPromotionService(d.getType()))
                .map(s -> s.calculateDiscount(cartLines, totalOriginPrice))
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        return totalOriginPrice.subtract(totalDiscountPrice);
    }

}

